package com.example.basic.web.service.remains.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.basic.base.impl.BaseEntityServiceImpl;
import com.example.basic.exception.ServiceException;
import com.example.basic.utils.PinyinUtils;
import com.example.basic.utils.StringUtils;
import com.example.basic.utils.WubiUtils;
import com.example.basic.web.enums.DataCodeEnum;
import com.example.basic.web.mapper.admire.AdmireMapper;
import com.example.basic.web.mapper.device.DeviceMapper;
import com.example.basic.web.mapper.newly.SysBacklogMapper;
import com.example.basic.web.mapper.newly.SysPdaFlowMapper;
import com.example.basic.web.mapper.remains.RemainsInfoMapper;
import com.example.basic.web.mapper.zoneDepot.ZoneDepotMapper;
import com.example.basic.web.model.admire.Admire;
import com.example.basic.web.model.device.Device;
import com.example.basic.web.model.newly.SysBacklog;
import com.example.basic.web.model.newly.SysPdaFlow;
import com.example.basic.web.model.notice.InNotice;
import com.example.basic.web.model.pharmIn.PharmInRecord;
import com.example.basic.web.model.remains.RemainsInfo;
import com.example.basic.web.model.zoneDepot.ZoneDepot;
import com.example.basic.web.response.BindingInfoResponse;
import com.example.basic.web.response.RemainFlowVo;
import com.example.basic.web.service.common.CommonService;
import com.example.basic.web.service.dataCode.DataCodeService;
import com.example.basic.web.service.notice.InNoticeService;
import com.example.basic.web.service.pharmIn.PharmInRecordService;
import com.example.basic.web.service.remains.RemainsInfoService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.example.basic.utils.CheckUtil.notNull;


@Service
public class RemainsInfoServiceImpl extends BaseEntityServiceImpl<RemainsInfoMapper, RemainsInfo> implements RemainsInfoService {

    @Resource
    private RemainsInfoMapper remainsInfoMapper;

    @Resource
    private DataCodeService dataCodeService;

    @Resource
    private CommonService commonService;

    @Resource
    private InNoticeService inNoticeService;
    @Resource
    private PharmInRecordService pharmInRecordService;

    @Autowired
    private SysPdaFlowMapper sysPdaFlowMapper;

    @Autowired
    private SysBacklogMapper sysBacklogMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private ZoneDepotMapper zoneDepotMapper;

    @Autowired
    private AdmireMapper admireMapper;



    /**
     * 新增或更新
     * @param remainsInfo
     * @return
     */
    @Override
    public RemainsInfo addOrUpdate(RemainsInfo remainsInfo) {

        //参数校验
        checkParams(remainsInfo);

        //遗体信息编码不为空，修改遗体信息信息
        if(StringUtils.notEmptyParams(remainsInfo.getRemainsCode())){
            notNull(remainsInfo.getId(),"唯一id不能为空");
            //校验遗体信息名称唯一
            LambdaQueryWrapper<RemainsInfo> lqw = new LambdaQueryWrapper<>();
            lqw.eq(RemainsInfo::getIdNo,remainsInfo.getIdNo());
            lqw.ne(RemainsInfo::getRemainsCode,remainsInfo.getRemainsCode());
            RemainsInfo localRole = this.mapper.selectOne(lqw);
            if(localRole != null){
                throw new ServiceException("遗体信息已存在");
            }

            //通过遗体获取入库单
            InNotice inNotice = inNoticeService.findByRemainsCode(remainsInfo.getRemainsCode());

            if(inNotice != null){
                throw new ServiceException("不允许修改");
            }

            preUpdate(remainsInfo);
        }else {
            //校验遗体信息名称唯一
            LambdaQueryWrapper<RemainsInfo> lqw = new LambdaQueryWrapper<>();
            lqw.eq(RemainsInfo::getIdNo,remainsInfo.getIdNo());
            RemainsInfo localRole = this.mapper.selectOne(lqw);
            if(localRole != null){
                throw new ServiceException("遗体信息已存在");
            }

            preCreate(remainsInfo);
            //生成遗体信息编码
            String remainsCode = dataCodeService.generateDataCodeNo(DataCodeEnum.REMAINS_CODE.getType());
            remainsInfo.setRemainsCode(remainsCode);
        }

        //直接火化，火化时间为当天
        if("1".equals(remainsInfo.getCremationType())){
            remainsInfo.setCremationTime(commonService.getDataBaseTime());
        }

        //生成拼音码五笔码
        generatePyWbCode(remainsInfo);

        save(remainsInfo);

        return remainsInfo;
    }

    /**
     * 参数校验
     * @param remainsInfo
     */
    private void checkParams(RemainsInfo remainsInfo) {
        notNull(remainsInfo,"实体不能为空");
        notNull(remainsInfo.getName(),"姓名不能为空");
        notNull(remainsInfo.getSexCode(),"性别不能为空");
        notNull(remainsInfo.getAge(),"年龄不能为空");
        notNull(remainsInfo.getBirthday(),"出生日期不能为空");
        notNull(remainsInfo.getContactName(),"联系人不能为空");
        notNull(remainsInfo.getContactPhone(),"联系方式不能为空");
        notNull(remainsInfo.getCremationType(),"火化方式不能为空");
        notNull(remainsInfo.getAdmire(),"瞻仰不能为空");
    }

    /**
     * @create 生成五笔码、拼音码
     * @param remainsInfo 模型实体类
     */
    private void generatePyWbCode(RemainsInfo remainsInfo) {
        // 获取遗体信息名
        String name = StringUtils.safeToString(remainsInfo.getName(), "");
        // 生成拼音码
        if("".equals(StringUtils.safeToString(remainsInfo.getPyCode(),"").replaceAll(" ",""))) {
            String userNamePinyin = PinyinUtils.getSimplePinYin(name);
            remainsInfo.setPyCode(userNamePinyin);
        }
        // 生成拼音码
        if("".equals(StringUtils.safeToString(remainsInfo.getWbCode(),"").replaceAll(" ",""))) {
            String userNameWubi = WubiUtils.getSimpleWuBi(name);
            remainsInfo.setWbCode(userNameWubi);
        }
    }

    /**
     * 删除遗体信息
     * @param remainsCode 遗体信息编码
     * @return
     */
    @Override
    public Boolean remove(String remainsCode) {
        notNull(remainsCode,"遗体信息编码不能为空");

        LambdaQueryWrapper<RemainsInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(RemainsInfo::getRemainsCode,remainsCode);
        RemainsInfo localRole = this.mapper.selectOne(lqw);

        if(localRole == null){
            throw new ServiceException("未获取到需要删除的遗体信息信息");
        }

        if(this.mapper.deleteById(localRole) > 0){
            return true;
        }

        throw new ServiceException("删除失败");
    }


    /**
     * 遗体信息列表
     * @param queryPage 分页
     * @param searchParam 名称
     * @param sex  性别
     * @param cremation 火化方式
     * @return
     */
    @Override
    public IPage<RemainsInfo> queryList(Page<RemainsInfo> queryPage,  String searchParam, String sex,String cremation) {

        return this.mapper.queryList(queryPage,searchParam,sex,cremation);
    }

    /**
     * 待入库列表
     * @param queryPage 分页
     * @param searchParam 模糊搜索(拼音码,五笔码,名称)
     * @param sex 性别 0-全部
     * @param beginTime 开始日期 yyyy-mm-dd
     * @param endTime 结束日期 yyyy-mm-dd
     * @return
     */
    @Override
    public IPage<RemainsInfo> waitInList(Page<RemainsInfo> queryPage, String searchParam, String sex, String beginTime, String endTime) {
        return this.mapper.waitInList(queryPage,searchParam,sex,beginTime,endTime);
    }

    /**
     * 遗体信息详情
     * @param remainsCode 遗体编码
     * @return
     */
    @Override
    public RemainsInfo detail(String remainsCode) {
        notNull(remainsCode,"遗体信息编码不能为空");

        LambdaQueryWrapper<RemainsInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(RemainsInfo::getRemainsCode,remainsCode);
        return this.mapper.selectOne(lqw);
    }

    /**
     * 遗体列表
     * @param searchParam 模糊搜索(拼音码,五笔码,名称)
     * @return
     */
    @Override
    public List<RemainsInfo> queryByBinding(String searchParam) {
        return this.mapper.queryByBinding(searchParam);
    }

    /**
     * 绑定信息详情
     * @param deviceCode 设备编码
     * @param remainsCode 担架板编码
     * @return
     */
    @Override
    public BindingInfoResponse bindingDetail(String deviceCode, String remainsCode) {

        BindingInfoResponse bindingInfoResponse = this.mapper.bindingDetail(deviceCode, remainsCode);

        if(bindingInfoResponse != null && StringUtils.notEmptyParams(bindingInfoResponse.getDocumentNo())){
            if(bindingInfoResponse.getDocumentNo().contains("RN")){
                InNotice inNotice = inNoticeService.detail(bindingInfoResponse.getDocumentNo());
                if(inNotice != null && inNotice.getStatus().equals("2")){
                    bindingInfoResponse.setDocumentStatus("2");
                }else {
                    bindingInfoResponse.setDocumentStatus("1");
                }
                bindingInfoResponse.setPharmCode(inNotice.getPharmCode());
                bindingInfoResponse.setZoneCode(inNotice.getZoneCode());
                bindingInfoResponse.setDepotCode(inNotice.getDepotCode());
                bindingInfoResponse.setPharmName(inNotice.getPharmName());
                bindingInfoResponse.setZoneName(inNotice.getZoneName());
                bindingInfoResponse.setCremationRoomName(inNotice.getCremationRoomName());
                bindingInfoResponse.setAdmireHallName(inNotice.getAdmireHallName());
            }else {
                PharmInRecord pharmInRecord = pharmInRecordService.detail(bindingInfoResponse.getDocumentNo());
                InNotice inNotice = inNoticeService.detail(pharmInRecord.getInNoticeCode());
                bindingInfoResponse.setPharmCode(inNotice.getPharmCode());
                bindingInfoResponse.setZoneCode(inNotice.getZoneCode());
                bindingInfoResponse.setDepotCode(inNotice.getDepotCode());
                bindingInfoResponse.setPharmName(inNotice.getPharmName());
                bindingInfoResponse.setZoneName(inNotice.getZoneName());
                bindingInfoResponse.setCremationRoomName(inNotice.getCremationRoomName());
                bindingInfoResponse.setAdmireHallName(inNotice.getAdmireHallName());
                bindingInfoResponse.setDocumentStatus("2");
            }
        }
        return bindingInfoResponse;
    }

    /**
     * 今日数量统计
     * @return
     */
    @Override
    public Map homeRemainsCount() {
        return this.mapper.homeRemainsCount();
    }

    /**
     * 特殊环节占比
     * @param isAll 1-今日，2-历史
     * @return
     */
    @Override
    public List<RemainsInfo> homeSpecialCount(String isAll) {
        return this.mapper.homeSpecialCount(isAll);
    }

    /**
     * 根据日期获取遗体数量
     * @param beginDate 开始日期
     * @param endDate 结束日期
     * @return
     */
    @Override
    public List<RemainsInfo> homeWeekCount(Date beginDate, Date endDate) {
        return this.mapper.homeWeekCount(beginDate,endDate);
    }

    /**
     * pda-遗体信息详情
     * @param remainsCode
     * @return
     */
    @Override
    public BindingInfoResponse remainsInfo(String remainsCode) {
        BindingInfoResponse bindingInfoResponse = this.mapper.remainsInfo(remainsCode);

        if(bindingInfoResponse != null && StringUtils.notEmptyParams(bindingInfoResponse.getDocumentNo())){
            if(bindingInfoResponse.getDocumentNo().contains("RN")){
                InNotice inNotice = inNoticeService.detail(bindingInfoResponse.getDocumentNo());
                if(inNotice != null && inNotice.getStatus().equals("2")){
                    bindingInfoResponse.setDocumentStatus("2");
                    bindingInfoResponse.setPharmCode(inNotice.getPharmCode());
                    bindingInfoResponse.setZoneCode(inNotice.getZoneCode());
                    bindingInfoResponse.setDepotCode(inNotice.getDepotCode());
                    bindingInfoResponse.setPharmName(inNotice.getPharmName());
                    bindingInfoResponse.setZoneName(inNotice.getZoneName());
                    bindingInfoResponse.setCremationRoomName(inNotice.getCremationRoomName());
                    bindingInfoResponse.setAdmireHallName(inNotice.getAdmireHallName());
                }else {
                    bindingInfoResponse.setDocumentStatus("1");
                }
            }else {
                PharmInRecord pharmInRecord = pharmInRecordService.detail(bindingInfoResponse.getDocumentNo());
                InNotice inNotice = inNoticeService.detail(pharmInRecord.getInNoticeCode());
                bindingInfoResponse.setPharmCode(inNotice.getPharmCode());
                bindingInfoResponse.setZoneCode(inNotice.getZoneCode());
                bindingInfoResponse.setDepotCode(inNotice.getDepotCode());
                bindingInfoResponse.setPharmName(inNotice.getPharmName());
                bindingInfoResponse.setZoneName(inNotice.getZoneName());
                bindingInfoResponse.setCremationRoomName(inNotice.getCremationRoomName());
                bindingInfoResponse.setAdmireHallName(inNotice.getAdmireHallName());
                bindingInfoResponse.setDocumentStatus("2");
            }
        }
        return bindingInfoResponse;
    }

    @Override
    public RemainFlowVo detailPda(String remainsCode, String userId, String roleCode) {

        LambdaQueryWrapper<RemainsInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(RemainsInfo::getRemainsCode,remainsCode);
        RemainsInfo remainsInfo = this.mapper.selectOne(lqw);
        if(remainsInfo == null){
            throw new ServiceException("未获取到需要遗体信息");
        }

        RemainFlowVo remainFlowVo = new RemainFlowVo();
        remainFlowVo.setRemainsId(remainsInfo.getId());
        remainFlowVo.setRemainsCode(remainsInfo.getRemainsCode());
        remainFlowVo.setRemainsName(remainsInfo.getName());
        remainFlowVo.setRemainsSex(remainsInfo.getSexCode());
        remainFlowVo.setRemainsAge(remainsInfo.getAge());



        LambdaQueryWrapper<SysPdaFlow> flowLqw = new LambdaQueryWrapper<>();
        flowLqw.eq(SysPdaFlow::getRemainsId,remainsInfo.getId());
        SysPdaFlow sysPdaFlow = sysPdaFlowMapper.selectOne(flowLqw);

        if (ObjectUtil.isNotEmpty(sysPdaFlow)) {
            if (ObjectUtil.isNotEmpty(sysPdaFlow.getAdmireId())) {
                Admire admire = admireMapper.selectById(sysPdaFlow.getAdmireId());
                if (ObjectUtil.isNotEmpty(admire)) {
                    remainFlowVo.setAdmireName(admire.getName());
                }

            }
        }

        //除了信息录入人员 其他人员需要判断是否有该yt的待办 没有的话返回尚未走到该流程
        if(!roleCode.equals("000015")){
            //非信息录入人员
            if (sysPdaFlow == null) {
                throw new ServiceException("该遗体信息还未录入流程");
            }
            BeanUtils.copyProperties(sysPdaFlow,remainFlowVo);

            //不为空.返回流程信息
            if (ObjectUtil.isNotEmpty(sysPdaFlow.getPositionId())){
                Device device = deviceMapper.selectById(sysPdaFlow.getPositionId());
                if (ObjectUtil.isNotEmpty(device)){
                    remainFlowVo.setJieBoPosition(device.getDeviceName());
                    remainFlowVo.setDeviceType(device.getDeviceType());
                }
            }
            if(!roleCode.equals("000017")) {
                LambdaQueryWrapper<SysBacklog> backlogLambdaQueryWrapper = new LambdaQueryWrapper<>();
                backlogLambdaQueryWrapper.eq(SysBacklog::getSysUserId, userId);
                backlogLambdaQueryWrapper.eq(SysBacklog::getFlowId, sysPdaFlow.getId());
                backlogLambdaQueryWrapper.eq(SysBacklog::getStatus, 0);
                SysBacklog sysBacklog = sysBacklogMapper.selectOne(backlogLambdaQueryWrapper);
                if (sysBacklog == null) {
                    throw new ServiceException("该遗体信息还未走到该流程");
                } else {
                    remainFlowVo.setBackLogId(sysBacklog.getId());
                }
            }
        }else {
            //信息录入人员 如果流程信息已录入则提示不要重复录入
            if (sysPdaFlow != null) {
                throw new ServiceException("该遗体信息已录入流程,请勿重复录入");
            }else {
                //还未录入 只返回基础信息
            }
        }
        return remainFlowVo;
    }

    @Override
    public RemainFlowVo selectFlow(String remainsCode, String userId, String roleCode) {
        LambdaQueryWrapper<RemainsInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(RemainsInfo::getRemainsCode,remainsCode);
        RemainsInfo remainsInfo = this.mapper.selectOne(lqw);
        if(remainsInfo == null){
            throw new ServiceException("未获取到需要遗体信息");
        }

        RemainFlowVo remainFlowVo = new RemainFlowVo();
        remainFlowVo.setRemainsId(remainsInfo.getId());
        remainFlowVo.setRemainsCode(remainsInfo.getRemainsCode());
        remainFlowVo.setRemainsName(remainsInfo.getName());
        remainFlowVo.setRemainsSex(remainsInfo.getSexCode());
        remainFlowVo.setRemainsAge(remainsInfo.getAge());



        LambdaQueryWrapper<SysPdaFlow> flowLqw = new LambdaQueryWrapper<>();
        flowLqw.eq(SysPdaFlow::getRemainsId,remainsInfo.getId());
        SysPdaFlow sysPdaFlow = sysPdaFlowMapper.selectOne(flowLqw);

        if (sysPdaFlow == null) {
            throw new ServiceException("该遗体信息还未录入流程");
        }


            if (ObjectUtil.isNotEmpty(sysPdaFlow.getAdmireId())) {
                Admire admire = admireMapper.selectById(sysPdaFlow.getAdmireId());
                if (ObjectUtil.isNotEmpty(admire)) {
                    remainFlowVo.setAdmireName(admire.getName());
                }


        }


        BeanUtils.copyProperties(sysPdaFlow,remainFlowVo);

        //不为空.返回流程信息
        if (ObjectUtil.isNotEmpty(sysPdaFlow.getPositionId())){
            Device device = deviceMapper.selectById(sysPdaFlow.getPositionId());
            if (ObjectUtil.isNotEmpty(device)){
                remainFlowVo.setJieBoPosition(device.getDeviceName());
                remainFlowVo.setDeviceType(device.getDeviceType());
            }
        }

//        //除了信息录入人员 其他人员需要判断是否有该yt的待办 没有的话返回尚未走到该流程
//        if(!roleCode.equals("000015")){
//            //非信息录入人员
//
//
//
//            if(!roleCode.equals("000017")) {
//                LambdaQueryWrapper<SysBacklog> backlogLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                backlogLambdaQueryWrapper.eq(SysBacklog::getSysUserId, userId);
//                backlogLambdaQueryWrapper.eq(SysBacklog::getFlowId, sysPdaFlow.getId());
//                backlogLambdaQueryWrapper.eq(SysBacklog::getStatus, 0);
//                SysBacklog sysBacklog = sysBacklogMapper.selectOne(backlogLambdaQueryWrapper);
//                if (sysBacklog == null) {
//                    throw new ServiceException("该遗体信息还未走到该流程");
//                } else {
//                    remainFlowVo.setBackLogId(sysBacklog.getId());
//                }
//            }
//        }else {
//            //信息录入人员 如果流程信息已录入则提示不要重复录入
//            if (sysPdaFlow != null) {
//                throw new ServiceException("该遗体信息已录入流程,请勿重复录入");
//            }else {
//                //还未录入 只返回基础信息
//            }
//        }
        return remainFlowVo;
    }
}
